/*
 * @Author: Gjx 1308613747@qq.com
 * @Date: 2022-07-05 13:58:46
 * @LastEditors: Gjx 1308613747@qq.com
 * @LastEditTime: 2022-07-06 14:38:13
 * @FilePath: /jsCode/promise.js
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */

// let p = new Promise(function (resolve, reject) {
//   console.log("start === > ");
//   setTimeout(function () {
//     resolve("data1 === > ");
//   }, 1000);
// });

// p.then(
//   (v) => {
//     console.log("success： " + v);
//   },
//   (v) => {
//     console.log("error： " + v);
//   }
// );

// console.log("end === > ");

// 输出
// start === >
// end === >
// success： data1 === >

/**
 * 综上可得
 * 1. Promise 是构造函数 new 出的实例 有 then 方法
 * 2. new promise 传递参数为一个 function 称为执行器函数(executor) executor 会被立即调用 【start === > 】 优先输出
 * 3. executor 接受 两个参数 同时这两个参数 也是函数
 * 4. 存在实例状态 等待 成功 结束 调用完成
 * 5. 实例状态一经改变，便不能修改
 * 6. 实例 then 中参数有两个状态   success 和 error
 */

/**
 * 自定义 构造函数 promise 方法
 * @function CustomPromise
 * @param {*} executor
 */
const CustomPromise = function (executor) {
  const _this = this;
  _this.successResult = undefined; // 初始化 resolve 实例值
  _this.errorResult = undefined; // 初始化 reject 实例值
  _this.status = "pending"; // 初始化实例状态
  _this.onResolveCallbacks = []; // 初始化 then 方法中的第一个参数 捕捉 resolve
  _this.onRejectCallbacks = []; // 初始化 then 方法中的第二个参数 捕捉 reject

  // 成功
  function resolve(data) {
    // 当 status 发生改变便不能再次修改
    if (_this.status === "pending") {
      _this.status = "resolve"; // 成功
      _this.successResult = data;
      _this.onResolveCallbacks.forEach(function (fn) {
        fn();
      });
    }
  }

  // 失败
  function reject(error) {
    if (_this.status === "pending") {
      _this.status = "reject"; // 失败
      _this.errorResult = error;
      _this.onRejectCallbacks.forEach(function (fn) {
        fn();
      });
    }
  }

  // 结束
  function finish() {
    if (_this.status === "pending") {
      _this.status = "finally"; // 结束
      _this.errorResult = error;
    }
  }

  executor(resolve, reject, finish);
};

/**
 * 定义 promise 原型实例 then 方法
 */
CustomPromise.prototype.then = function (onResolve, onReject) {
  const _this = this;
  if (_this.status === "resolve") {
    onResolve(_this.successResult);
  }
  if (_this.status === "reject") {
    onReject(_this.errorResult);
  }

  if (_this.status === "pending") {
    // 订阅 resolve
    _this.onResolveCallbacks.push(function () {
      onResolve(_this.successResult);
    });
    // 订阅 reject
    _this.onRejectCallbacks.push(function(){
      onReject(_this.errorResult);
    })
  }
};

/**
 * 定义 promise 原型实例 catch 方法
 */
CustomPromise.prototype.catch = function (onResolve, onReject) {
  const _this = this;
  if (_this.status === "reject") {
    onReject(_this.errorResult);
  }
  if (_this.status === "pending") {
    // 订阅 reject
    _this.onRejectCallbacks.push(function(){
      onReject(_this.errorResult);
    })
  }
};

/**
 * 定义 promise 原型实例 finally 方法
 */
CustomPromise.prototype.finally = function (params) {};

/**
 * 定义 promise 原型实例 all 方法
 */
CustomPromise.prototype.all = function (params) {};

// 尝试使用
let p = new CustomPromise(function (resolve, reject) {
  console.log("start === > ");
  setTimeout(function() {
    resolve("data1 === > ");
  })
});
p.then(
  (v) => {
    console.log("success： " + v);
  },
  (v) => {
    console.log("error： " + v);
  }
)
// .catch(err => {
//   console.log("err", err);
// });
console.log("end === > ");
